package cfca.paperless.client.servlet._7_remote;

import java.io.File;
import java.io.FileInputStream;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import cfca.paperless.client.bean.MultiDataBean;
import cfca.paperless.client.bean.SealUserInfo;
import cfca.paperless.client.bean.SignLocation;
import cfca.paperless.client.servlet.PaperlessClient;
import cfca.paperless.client.servlet.PaperlessConfig;
import cfca.paperless.client.util.GUID;
import cfca.paperless.client.util.IoUtil;
import cfca.paperless.client.util.PaperlessUtil;
import cfca.paperless.client.util.PdfUtil;
import cfca.paperless.client.util.StrategyUtil;
import cfca.paperless.client.util.StringUtil;
import cfca.sadk.algorithm.common.Mechanism;
import cfca.sadk.util.Base64;
import cfca.sadk.util.KeyUtil;

public class SignAutoPdfProofHashTest01 {

    /**
     * Pdf证据hash签名
     * @param args
     * @throws IOException
     * @throws
     */
    public static void main(String[] args) throws Exception {
        try {
            long timeStart = System.currentTimeMillis();// 开始时间

            PaperlessClient clientBean = new PaperlessClient(PaperlessConfig.extUrl, 10000, 60000);// 无纸化辅助接口的访问URL

            String filePath = "./TestData/autoCalculatePdfHash.pdf";
            byte[] pdf = FileUtils.readFileToByteArray(new File(filePath));
            byte[] x509Cert = FileUtils.readFileToByteArray(new File("./TestData/cert/tl1024.cer"));
            PrivateKey privateKey = KeyUtil.getPrivateKeyFromPFX(new FileInputStream("./TestData/cert/tl1024.pfx"), "11111111");
            byte[] handwritingImage1 = FileUtils.readFileToByteArray(new File("./TestData/zhangfei.png"));
            byte[] handwritingData1 = handwritingImage1;
            byte[] identificationFrontData = FileUtils.readFileToByteArray(new File("./TestData/1.png"));
            byte[] identificationBackData = FileUtils.readFileToByteArray(new File("./TestData/2.png"));
            List<MultiDataBean> list = new ArrayList<MultiDataBean>();
            list.add(new MultiDataBean(handwritingData1, "handwritingData.dat", "media-id", "0"));//手写签名数据
            list.add(new MultiDataBean(handwritingImage1, "handwritingImage.png", "2"));//手写签名图片
            list.add(new MultiDataBean(identificationFrontData, "identificationFrontImage.png", "2"));//身份证正面
            list.add(new MultiDataBean(identificationBackData, "identificationBackImage.png", "2"));//身份证反面
            String proofHashAndMultiData1[] = PaperlessUtil.getProofHashAndMultiData(list);
            
            String proofHashXml = proofHashAndMultiData1[0];
            String pdfContentHash = PdfUtil.calculatePdfContentHash(pdf, new Mechanism(Mechanism.SHA1));
            proofHashXml = addProofToXml(proofHashXml, "pdfHash.pdf", pdfContentHash);
            //合成proofHash
            pdf = PdfUtil.compoundPdfDataByAttachment(pdf, proofHashXml.getBytes(), "proofHash.xml");
            //合成多媒体文件
            for(MultiDataBean multiDataBean : list) {
                pdf = PdfUtil.compoundPdfDataByAttachment(pdf, multiDataBean.getMultiData(), multiDataBean.getFileName());
            }
            
            SealUserInfo sealUserInfo = new SealUserInfo("张三a", "Z", "0003aa222158888", "15744659823", "北京", "签合同");
            String userInfoXml = PaperlessUtil.buildUserInfo(sealUserInfo, "2");//2代表远程印章
            // 操作员编码或者机构号
            String operatorCode = PaperlessConfig.operatorCode;
            // 渠道编码，可以为空
            String channelCode = PaperlessConfig.channelCode;
            
            SignLocation signLocation = new SignLocation("代理人签名", "R", 10, 10);
            // get pdf hash
            String strategyXml = StrategyUtil.createClientSealStrategyXml("业务", "china", handwritingImage1, signLocation, "");
            String systemNo = GUID.generateId();
            String returnMessage = clientBean.autoCalculatePdfHash(systemNo,pdf, null, strategyXml, operatorCode, channelCode);
            String code = StringUtil.getNodeText(returnMessage, "Code");
            if ("200".equals(code)) {
                System.out.println("OK:autoCalculatePdfHash");
                String pdfSealHash = StringUtil.getNodeText(returnMessage, "PdfSealHash");
                String pdfSealSource = StringUtil.getNodeText(returnMessage, "PdfSealSource");
                String pdfHashListXml = "<List><PdfHash><PdfSealHash>" + pdfSealHash + "</PdfSealHash><PdfSealSource></PdfSealSource><BizTypeCode></BizTypeCode></PdfHash></List>";
                String authCodeXml = "<AuthCode><AuthCodeValue>494581</AuthCodeValue>201607251611497705635264631397<AuthCodeId>201607231828542868450615837669</AuthCodeId></AuthCode>";
                String id = StringUtil.getNodeText(returnMessage, "Id");
                //对pdf hash签名
                String signMessage = clientBean.signAutoPdfProofHash(pdfHashListXml, userInfoXml, proofHashXml, "", operatorCode, channelCode);
                code = StringUtil.getNodeText(signMessage, "Code");
                if ("200".equals(code)) {
                    System.out.println("OK:autoCalculatePdfHash");
                    String pkcs7 = StringUtil.getNodeText(signMessage, "Pkcs7");
                    System.out.println("返回的pkcs7：" + pkcs7);
                    
                    byte[] sealedPdfData = clientBean.synthesizeOuterSignature(systemNo,Base64.decode(pkcs7), id, operatorCode, channelCode);
                    String errorRsString = PaperlessUtil.isError(sealedPdfData);

                    if ("".equals(errorRsString)) {
                        System.out.println("OK:synthesizeOuterSignature");
                        System.out.println(sealedPdfData.length);
                        IoUtil.write("./TestData/output/signAutoPdfProofHash-" + new File(filePath).getName() + ".pdf", sealedPdfData);
                    } else {
                        // 处理结果为异常，打印出错误码和错误信息
                        System.out.println("NG:synthesizeOuterSignature");
                        System.out.println(sealedPdfData.length);
                        System.out.println(new String(sealedPdfData, "UTF-8"));
                    }
                    
                } else {
                    System.out.println("" + signMessage);
                }
            } else {
                System.out.println("" + returnMessage);
            }
            long timeEnd = System.currentTimeMillis();// 结束时间
            System.out.println("time:" + (timeEnd - timeStart));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    
    public static String addProofToXml(String xmlContent, String fileName, String hash) throws DocumentException  {
        Document document = DocumentHelper.parseText(xmlContent);
        Element root = document.getRootElement();
        Element newElement = root.addElement("Proof");
        newElement.addAttribute("fileName", fileName);
        newElement.addAttribute("hash", hash);
        return document.asXML();

    }

}
